import React, { Component, ComponentClass } from 'react';
import Taro from '@tarojs/taro';
import {AtIcon, AtLoadMore, AtFloatLayout} from 'taro-ui'
import {connect} from 'react-redux'
import {View, Image, Input, Button, Navigator, Text} from '@tarojs/components'
import {CategoryListPageGood, Good, ScreenItem} from '../../utils/server.interface'
import {platform} from '../../utils/platform-settting.service'
import {http} from '../../utils/http'
import {
  GET_FORMAT_DATE,
  HOTEL_OUT_PRODUCT, IDENTITY_IS_SELLER,
  RESOURCE_URL,
  SCAN_BIND_SELLER,
  UPDATE_USER_SHARE_DATE
} from '../../constants/api'
import Calendar from '../components/calendar/calendar'
import {DateType} from '../../reducers/select-date'
import {user} from '../../utils/user.service'
import SmallGoodsBox from '../../components/small-goods-box/small-goods-box'
import {vcmonitor} from "../../utils/tools";
import {BAIDU_MAP_GEOCODING_API_URL, BAIDU_MAP_AK_KEY} from '../../constants/baidu'
import SupportBar from '../../components/support-bar/support-bar'
import {h5Wx} from "../../utils/h5.service";
import GzhAuth from "../../components/gzh-auth/gzh-auth"
import Share from "../../components/share/share";
import AdvertisementMember from "../../components/advertisement/member";
import {getMemberAdvertisement} from "../../utils/getCommonData";
import './index.scss'

type PageStateProps = {
  selectDate: DateType
}
type PageDispatchProps = {}

type PageOwnProps = {}

type PageState = {
  linkUri: any
  memberAdvertisement: any
  dataInfo: any
  goods: Good[]
  loadMoreStatus: "more" | "loading" | "noMore"
  searchKey: string
  showCalendar: boolean
  screen: (ScreenItem & { data: { label: string; value: string }[] })[]
  accordionOpen: { [key: string]: any }
  radioData: {
    price?: string
  }
  checkboxData: {
    [key: string]: string[]
  }
  drawerShow: boolean
  order: {
    price: 'DESC' | 'ASC'
    sale: 'DESC' | 'ASC'
  }
  diyPriceData: { max: string; min: string }
  starType: number
  thisIsOpened: boolean
  price: []
  hotelStar: []
  priceClick: number
  toggle: boolean
  isUser: boolean
  hotelClick: []
  hotelPrice: string
  platformSet: any
  outLocation: any
}

type IProps = PageStateProps & PageDispatchProps & PageOwnProps

interface Index {
  props: IProps
}

@connect(({selectDate}) => ({
  selectDate
}), () => ({}))

class Index extends Component {
  state: PageState = {
    dataInfo: null,
    platformSet: {},
    goods: [],
    loadMoreStatus: 'loading',
    searchKey: '',
    outLocation: false,
    showCalendar: false,
    isUser: true,
    screen: [],
    accordionOpen: {},
    radioData: {},
    checkboxData: {},
    drawerShow: false,
    order: {
      price: 'DESC',
      sale: 'DESC',
    },
    diyPriceData: {max: '', min: ''},
    starType: 0,
    thisIsOpened: false,
    price: [],
    hotelStar: [],
    priceClick: 0,
    hotelClick: [],
    hotelPrice: '',
    linkUri: '',
    memberAdvertisement: '',
    toggle: false
  }

  async UNSAFE_componentWillMount() {
    Taro.showLoading({title: '加载中...'})
    if (process.env.TARO_ENV === 'h5') {
      await h5Wx.getConfig()
    }
    const platformSet = await platform.getSetting()
    const goods = await this.getData(this.page)
    let screen: ScreenItem[] = []
    const screenRet = await http.post<ScreenItem[]>('api/v3/market/hotel/getHotelLable', {})
    const accordionOpen: { [key: string]: any } = {}
    const checkboxData = {}
    const radioData = {}
    if (screenRet && screenRet.length > 0) {
      const isPrice = screenRet.find(item => {
        return item.key === 'price'
      })
      if (isPrice !== undefined) {
        const priceData = isPrice.data
        this.setState({price: priceData})
      }
      const isStar = screenRet.find(item => {
        return item.key === 'star'
      })
      if (isStar !== undefined) {
        const starData = isStar.data
        this.setState({hotelStar: starData})
      }

    }
    if (screenRet && screenRet.length > 0) {
      screen = screenRet.map(item => {
        accordionOpen[item.key] = false
        // 选择不限默认值
        if (item.key !== 'price') {
          checkboxData[item.key] = ['0']
        } else {
          radioData[item.key] = '0'
        }

        const data: { name: string; typeid: string; value?: string; label?: string }[] = [{
          name: '不限',
          typeid: '0',
          label: '不限',
          value: '0',
        }]

        item.data.map(i => {
          i['label'] = i.name
          i['value'] = `${i.typeid}`
          data.push(i)
        })
        item.data = data
        return item

      })
    }
    this.setState({platformSet, goods, screen, accordionOpen, checkboxData, radioData})
    Taro.hideLoading()
  }

  async componentWillReceiveProps() {
    const goods = await this.getData(this.page)
    this.setState({goods})
  }

  async getDate(startDate, endDate) {
    const data = await http.HGet(GET_FORMAT_DATE, {start_date: startDate, end_date: endDate})
    this.setState({dataInfo: data.data})
  }

  async getLocationCity(longitude, latitude) {
    const baiduRet = await Taro.request<{ status: number; result: { addressComponent: { city: string } } }>({
      url: BAIDU_MAP_GEOCODING_API_URL,
      data: {
        ak: BAIDU_MAP_AK_KEY,
        location: latitude + ',' + longitude,
        coordtype: 'wgs84ll',
        output: 'json',
        pois: '0'
      }
    })
    if (baiduRet.statusCode != 200) {
      Taro.showToast({
        title: '通信失败',
        icon: 'none'
      })
    }
    const ret = baiduRet.data
    if (ret.status != 0) {
      Taro.showToast({
        title: '百度接口失败' + ret.status,
        icon: 'none'
      })
    }
    this.setState({
      latitude: ret.result.location.lat,
      longitude: ret.result.location.lng
    })
  }

  shareParams = ''

  async componentDidShow() {
    vcmonitor(this)
    const outLocation = Taro.getStorageSync('outCity') || Taro.getStorageSync('city')
    this.setState({outLocation, memberAdvertisement: await getMemberAdvertisement({ position: 'jiudian' })})
    this.shareParams = await user.getSellerParams()
    let link = '/common/hotel/outlands?' + this.shareParams
    if (process.env.TARO_ENV === 'h5') {
      link = window.location.origin + link
      const shareData = {
        title: platform.info.platformName,
        desc: '旅游线路',
        link,
        imgUrl: platform.info.platformLogo
      }
      h5Wx.share(shareData)
    } else {
      link += `&sKey=${Taro.getStorageSync('sKey' || '')}`
    }
    let isUser = true
    if (process.env.DISTINGUISH_IDENTITY) {
      const identityIsSeller = await http.get(IDENTITY_IS_SELLER, {})
      isUser = !identityIsSeller.isSeller
    }
    this.setState({linkUri: link, isUser})
    const bindSellerIds = Taro.getCurrentInstance().router.params.bindSellerId || ''
    const tempSellerIds = Taro.getCurrentInstance().router.params.tempSellerId || ''
    if ((bindSellerIds || tempSellerIds) && process.env.DISTINGUISH_IDENTITY) {
      http.HPost(SCAN_BIND_SELLER, { temp_seller_id: tempSellerIds, refer_seller_id: bindSellerIds });
    }
    await this.getDate(this.props.selectDate.start, this.props.selectDate.end)
  }

  onShareAppMessage() {
    if (process.env.TARO_ENV !== 'tt') {
      http.post(UPDATE_USER_SHARE_DATE, {})
    }
    return {
      title: platform.info.platformName,
      path: this.state.linkUri
    }
  }

  page = 1

  async getData(page) {
    const outLocation = Taro.getStorageSync('outCity')
    const data = {
      p: page,
      destination_city: outLocation.region_id || '',
    }
    const goods = (await http.post<CategoryListPageGood[]>(HOTEL_OUT_PRODUCT, data)) || []
    if (goods.length === 10) {
      this.setState({loadMoreStatus: 'more'})
    } else {
      this.setState({loadMoreStatus: 'noMore'})
    }
    return goods
  }

  onReachBottom() {
    if (this.state.loadMoreStatus != 'noMore') {
      this.setState({loadMoreStatus: 'loading'}, async () => {
        this.page++
        const goods = await this.getData(this.page)
        const old = this.state.goods
        this.setState({goods: [...old, ...goods]})
      })
    }
  }

  inputChange(e) {
    this.setState({searchKey: e.detail.value})
  }

  search() {
    const key = this.state.searchKey
    const latitude = this.state.latitude
    const longitude = this.state.longitude
    Taro.navigateTo({url: '/common/hotel/list?key=' + key + '&latitude=' + latitude + '&longitude=' + longitude + '&overseas=' + 1})
  }

  calendarSelect(value: { start: string; end: string; type: string; single: string; range: string[] }) {
    this.getDate(value.start, value.end)
    this.setState({showCalendar: false, startDate: value.start, endDate: value.end, durition: value.range.length + 1})
  }

  showCalendar() {
    this.setState({showCalendar: true})
  }

  changeAccordion(type, value) {
    const state = this.state.accordionOpen
    state[type] = value
    this.setState({accordionOpen: state})
  }

  radioChange(type, value) {
    const radioData = this.state.radioData
    radioData[type] = String(value)
    if (type === 'price') {
      this.setState({radioData, diyPriceData: {max: '', min: ''}})
    } else {
      this.setState({radioData})
    }
  }

  priceInput(type, e) {
    const diyPriceData: { [key: string]: string } = this.state.diyPriceData
    let {min, max} = diyPriceData
    if (type === 'min') min = e.detail.value
    if (type === 'max') max = e.detail.value
    this.setState({diyPriceData: {min, max}})
    return e.detail.value
  }

  priceCheck() {
    let {min, max} = this.state.diyPriceData
    if (parseInt(min) >= parseInt(max)) {
      Taro.showToast({title: '最小金额应该小于最大金额', icon: 'none'})
      max = parseInt(min) + 1 + ''
      this.setState({diyPriceData: {min, max}})
    }
  }

  checkboxChange(type, value) {
    const checkboxData = this.state.checkboxData
    let data = checkboxData[type] || []

    if (data.includes(value)) {
      data = data.splice(data.findIndex(value), 1)
    } else {
      data = value
    }
    if (data[data.length - 1] === '0') {
      data = ['0']
    }
    if (data.length > 1 && data.includes('0')) {
      data = data.splice(data.findIndex(item => item === '0') - 1, 1)
    }
    checkboxData[type] = data.length === 0 ? ['0'] : data
    this.setState({checkboxData})
  }

  changeOrder(type) {
    const order = this.state.order
    if (type) {
      order[type] = order[type] === 'ASC' ? 'DESC' : 'ASC'
    }
    this.setState({order, goods: [], loadMoreStatus: 'loading'}, async () => {
      this.page = 1
      const goods = await this.getData(this.page)
      this.setState({goods})
    })
  }

  screenConfirm() {
    this.setState({drawerShow: false, goods: [], loadMoreStatus: 'loading'}, async () => {
      this.page = 1
      const goods = await this.getData(this.page)
      this.setState({goods})
    })
  }

  screenCancel() {
    const {radioData, checkboxData} = this.state
    Object.keys(radioData).map(item => {
      radioData[item] = '0'
    })
    Object.keys(checkboxData).map(item => {
      checkboxData[item] = ['0']
    })
    this.setState({radioData, checkboxData, diyPriceData: {min: '', max: ''}})
  }

  showDrawerItem(type) {
    const {accordionOpen} = this.state
    Object.keys(accordionOpen).map(item => {
      accordionOpen[item] = false
    })
    accordionOpen[type] = true
    this.setState({drawerShow: true}, () => {
      const timer = setTimeout(() => {
        this.setState({accordionOpen});
        clearTimeout(timer);
      }, 400)
    })
  }

  priceClick(id, range) {
    if (id == this.state.priceClick) {
      this.setState({priceClick: 0, hotelPrice: ''})
    } else {
      this.setState({priceClick: id, hotelPrice: range})
    }
  }

  hotelNum = [];

  starClick(id) {
    if (this.hotelNum.indexOf(id) >= 0) {
      const index = this.hotelNum.findIndex(item => item === id)
      this.hotelNum.splice(index, 1)
    } else {
      const hotelNum = this.hotelNum
      hotelNum.push(id)
      this.hotelNum = hotelNum
    }
    this.setState({hotelClick: this.hotelNum})

  }

  screenShow() {
    this.setState({thisIsOpened: true})
  }

  searchHotel() {
    Taro.navigateTo({url: '/common/hotel/list?price=' + this.state.hotelPrice + '&star=' + this.state.hotelClick})
  }

  render() {
    const {
      linkUri,
      outLocation,
      loadMoreStatus,
      goods,
      showCalendar,
      thisIsOpened,
      price,
      hotelStar,
      priceClick,
      dataInfo,
      memberAdvertisement,
      platformSet,
      isUser,
      hotelClick
    } = this.state
    return (
      <View className='hotel-list-root outland'>
        <GzhAuth />
        <View className='main'>
          <Image className='main-bg' src={RESOURCE_URL + platform.info.hotel_background}
            mode='widthFix'
          />
          <View className='main-box'>
            <View className='tabs'>
              <View className='tab domestic'><Navigator className='tab-mask' openType='redirect'
                url='/common/hotel/index'
              >国内</Navigator></View>
              <View className='tab active-new outlands'>
                海外
              </View>
            </View>
            <View className='box'>
              <View style='overflow: hidden;border-bottom: 1px solid #e7e7e5;position: relative;'>
                <Navigator className='location' style='width:100%;float:left;border:none;' url='/common/hotel/city'
                  hoverClass='none'
                >
                  <View className='city'
                    style='width:80%'
                  >{outLocation.area_name ? outLocation.area_name : '选择城市'}</View>
                  <View className='get-location'>
                    <View>
                      <AtIcon value='chevron-right' size='16' color='#999' />
                    </View>
                  </View>
                </Navigator>
              </View>
              {dataInfo && <View className='date' onClick={this.showCalendar.bind(this)}>
                <View className='text-box'>
                  <View className='select-date'>
                    <View className='desc'>入住日期</View>
                    <View className='title'>{dataInfo.startDateObj.month + '月' + dataInfo.startDateObj.day + '日'}</View>
                  </View>
                  <View className='select-date day-nums'>
                    <Text className='desc' decode>&nbsp;</Text>
                    <View className='days'>{dataInfo.day}晚</View>
                  </View>
                  <View className='select-date'>
                    <View className='desc'>退房日期</View>
                    <View className='title'>{dataInfo.endDateObj.month + '月' + dataInfo.endDateObj.day + '日'}</View>
                  </View>
                </View>
              </View>}
              <View className='scenic'>
                <Input className='input' placeholder='试试搜索喜欢的酒店' confirm-type='search'
                  placeholder-className='holder-className' onInput={this.inputChange.bind(this)}
                />
              </View>
              <View className='screen' onClick={this.screenShow.bind(this)}>
                <Input className='input' placeholder='搜索酒店星级/价格' disabled />
              </View>

              <View className='btn'>
                <Button form-type='submit' data-type='click' className='button'
                  onClick={this.search.bind(this)}
                >查找全部酒店</Button>
              </View>
            </View>
          </View>
        </View>
        {(process.env.P_ENV === 'vc' || process.env.P_ENV === 'kunxin') && !!platformSet && !!platformSet.applicationOpenVip && memberAdvertisement && <View style='margin: 0 10px;'>
          <AdvertisementMember url={memberAdvertisement} />
        </View>}
        <View className='other'>
          {goods.length > 0 && <View className='recommend'>为您推荐</View>}
          {goods.length > 0 && <View className='goods-box'>
            <SmallGoodsBox data={goods} />
          </View>}
          {goods.length == 0 && <View className='listNull'>
            <Image src={`${RESOURCE_URL}/resources/images/shopnull.png`} mode='widthFix' />
            <View className='text'>什么都没有,去看看别的吧~</View>
          </View>}
        </View>
        <AtLoadMore status={loadMoreStatus} noMoreText='' moreBtnStyle='border:none;' moreText='加载更多' />
        <SupportBar />
        {showCalendar && <Calendar onClose={() => {
          this.setState({showCalendar: false})
        }} type='range' onConfirm={this.calendarSelect.bind(this)}
        />}
        <View className='screenBox'>
          <AtFloatLayout isOpened={thisIsOpened} onClose={() => {
            this.setState({thisIsOpened: false})
          }}
          >
            <View className='priceTit'>价格</View>
            <View className='hotelPrice'>
              {price.map((item) =>
                <View className={priceClick === item.typeid ? 'active' : 'priceLabel'}
                  onClick={this.priceClick.bind(this, item.typeid, item.range)} id={item.range}
                >
                  {item.name}
                </View>
              )}
            </View>
            <View className='starTypeTit'>星级</View>
            <View className='starTypeBox'>
              {hotelStar.map((item) =>
                <View className={hotelClick.indexOf(item.typeid) >= 0 ? 'active' : 'starType'}
                  onClick={this.starClick.bind(this, item.typeid)}
                >
                  {item.name}
                </View>
              )}
            </View>
            <Button className='searchHotel' onClick={this.searchHotel.bind(this)}>查询</Button>
          </AtFloatLayout>
        </View>
        {linkUri && process.env.P_ENV !== 'lx' && <Share isUser={isUser} linkUri={linkUri} />}
      </View>
    )
  }
}

export default Index as ComponentClass<PageOwnProps, PageState>
